﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using CommonClasses.Model;
using Eco.ObjectRepresentation;
using System.IO;
namespace ErrList
{
    /// <summary>
    /// Контрол для отображения ошибок компиляции
    /// </summary>
    public partial class ErrList : UserControl
    {

        #region private Fields
        /// <summary>
        /// Среда ECO
        /// </summary>
        private IEcoServiceProvider serviceProvider;

        /// <summary>
        /// Картинка ошибки
        /// </summary>
        private Bitmap ErrorBitmap;


        /// <summary>
        /// Обображаемые данные
        /// </summary>
        private List<Error> errors= new List<Error>();
        #endregion


        #region public Events and Invokers
        /// <summary>
        /// Обработчик при выборе ошибки
        /// </summary>
        /// <param name="error">ошибка</param>
        public delegate void ErrorSelectedHandler(Error error);

        /// <summary>
        /// Событие: выбрали ошибку
        /// </summary>
        public event ErrorSelectedHandler ErrorSelectedEvent;

        /// <summary>
        /// Выбрать ошибку
        /// </summary>
        /// <param name="error">ошибка</param>
        private void ErrorSelected(Error error)
        {
            if (ErrorSelectedEvent != null)
                ErrorSelectedEvent(error);
        }
        #endregion


        /// <summary>
        /// Заполнить контрол список ошибок имеющимися ошибками
        /// </summary>
        private void FillErrorList()
        {
            dgvErrorList.Rows.Clear();
            foreach (Error error in errors)
                dgvErrorList.Rows.Add(ErrorBitmap,
                    errors.IndexOf(error) + 1,
                    error.Message,
                    (error.Editor != null ? Path.GetFileNameWithoutExtension((error.Editor.Object as IDocumentEditor).Path) : "нет документа"),
                    error.Point!= null ?  error.Point.Point.Y.ToString() : null,
                    error.Point!=null ?  error.Point.Point.X.ToString() : null);
            dgvErrorList.Invalidate(true);
        }


        /// <summary>
        /// Добавить в список ошибок все ошибки из отчета
        /// </summary>
        /// <param name="errorReport">отчет</param>
        public void AddErrorReport(ErrorReport errorReport)
        {
            foreach(Error error in errorReport.Errors)
                errors.Add(error);
            FillErrorList();
        }


        /// <summary>
        /// Добавить ошибку в список ошибок
        /// </summary>
        /// <param name="error">ошибка</param>
        public void AddError(Error error)
        {
            errors.Add(error);
            FillErrorList();
        }


        /// <summary>
        /// Очистить весь список ошибок
        /// </summary>
        public void ClearErrors()
        {
            // удалим ошибки по-человечески
            errors.ForEach(err => 
            {
                if (err.CompilationUnit!= null)
                    err.CompilationUnit.AsIObject().Delete();
                err.Editor = null;
                err.Point.AsIObject().Delete();
                err.AsIObject().Delete();
            });
            errors.Clear();
            FillErrorList();
        }

        /// <summary>
        /// Конструктор для дизайнера
        /// </summary>
        public ErrList()
        {
            ErrorBitmap = global::ErrList.Properties.Resources.Error;
            ErrorBitmap.MakeTransparent(global::ErrList.Properties.Resources.Error.GetPixel(0, 0));
            InitializeComponent();
        }

        /// <summary>
        /// Конструктор 
        /// </summary>
        /// <param name="serviceProvider">провайдер сервисов ECO</param>
        public ErrList(IEcoServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
            ErrorBitmap = global::ErrList.Properties.Resources.Error;
            ErrorBitmap.MakeTransparent(global::ErrList.Properties.Resources.Error.GetPixel(0,0));
            InitializeComponent();
        }


        #region Event handlers

        /// <summary>
        /// Обработчик двойного нажатия на ошибку на контроле
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">DataGridViewCellMouseEventArgs</param>
        private void dgvErrorList_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex > -1)
                ErrorSelected(errors[ int.Parse(dgvErrorList.Rows[e.RowIndex].Cells[1].Value.ToString()) - 1]);


        }

        /// <summary>
        /// Обработчик нажатия на кнопку очистки списка ошибок
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">EventArgs</param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            ClearErrors();
        }
        
        #endregion


    }
}